// --- 这里是unity相关的tools

using System;
using System.IO;
using Newtonsoft.Json; //引用命名空间
using System.Collections.Generic;
using System.Collections;
using System.Reflection;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEditor;
using UnityEngine.UI;
using DG.Tweening;
//using UnityEditor.Tilemaps;

namespace AppFileTools
{
    // streaming data文件管理, 若android则自动转persistent data
    public class FileObject
    {
        // 如果不存在配置文件, 则创建之
        public bool create_if_not_exists = false;
        
        /// <summary>
        /// 文件对象, 例如用户配置文件
        /// </summary>
        /// <param name="file_name">文件名</param>
        /// <param name="dir_name">文件夹命</param>
        /// <param name="overwrite">是否覆盖</param>
        /// <param name="is_json_content">目标内容是否json格式</param>
        /// <param name="merge_old_dc">合并旧字典</param>
        /// <param name="create_if_not_exists">若文件不存在则创建之</param>
        public FileObject(string file_name, string dir_name = "", bool overwrite = false, bool is_json_content = true,
            bool merge_old_dc = true, bool create_if_not_exists = true)
        {
            persistent_file_path = my_get_file_path(file_name, dir_name, is_persistent: true);
            streaming_file_path = my_get_file_path(file_name, dir_name, is_persistent: false);
            
            this.is_json_content = is_json_content;
            this.merge_old_dc = merge_old_dc;   
            this.overwrite = overwrite;
            this.file_name = file_name;
            this.dir_name = dir_name;
            this.create_if_not_exists = create_if_not_exists;
            reaload_content(overwrite: overwrite, merge_old_dc: merge_old_dc);
        }

        public bool is_json_content;
        public bool merge_old_dc;
        public bool overwrite;

        public Dictionary<string, object> content_dc;
        public string content_text;

        public string persistent_file_path;
        public string streaming_file_path;
        public string relative_file_path;
        public string file_name;
        public string dir_name;
        
        // 合并字典的函数
        public static Dictionary<string, object> MergeDictionaries(Dictionary<string, object> dict1,
            Dictionary<string, object> dict2, bool overwrite = false)
        {
            Dictionary<string, object> mergedDictionary = new Dictionary<string, object>(dict1);
            foreach (var kvp in dict2)
            {
                if (overwrite || !mergedDictionary.ContainsKey(kvp.Key))
                {
                    BdUtils.log(overwrite, "~~~ MergeDictionaries overwrite kvp:", kvp.Key, ", ", kvp.Value);
                    mergedDictionary[kvp.Key] = kvp.Value;
                }
            }

            return mergedDictionary;
        }

        public void open_dir(bool is_persistent_dir = false)
        {
            var parent_dir_path = is_persistent_dir
                ? Directory.GetParent(persistent_file_path)
                : Directory.GetParent(streaming_file_path);
            // BdUtils.log("=== open parent_dir_path:", parent_dir_path);
            // BdUtils.CommandUtils.run_bash($"start {parent_dir_path}");
            // BdUtils.CommandUtils.run_shell($"start {parent_dir_path}");
            string cmd = BdUtils.is_windows_platform() ? $"start {parent_dir_path}" : $"open {parent_dir_path}";
            BdUtils.CommandUtils.run_cmd(cmd);
        }

        public void reaload_content(bool overwrite = false, bool merge_old_dc = true)
        {
            bool is_exists_file = BdUtils.exists_file(streaming_file_path);
            if (!is_exists_file)
            {
                if (create_if_not_exists)
                {
                    // BdUtils.assert(!BdUtils.exists_file(persistent_file_path), $"咋`streaming_file_path`不存在, 但`persistent_file_path`存在? streaming_file_path: {streaming_file_path}");
                    if (BdUtils.exists_file(persistent_file_path))
                    {
                        this.content_dc = load_dict(is_persistent: true);
                    }
                    else
                    {
                        this.content_dc = new Dictionary<string, object>();
                    }
                    save();
                    return;
                }
                else
                {
                    BdUtils.raise_exception_error_func($"配置文件不存在? `streaming_file_path`: [{streaming_file_path}]");
                }
            }
            
            // streamingData中的配置文件是初始变量, persistentData中的配置文件是用户数据, 默认`overwrite`不进行覆盖
            if (File.Exists(persistent_file_path) && merge_old_dc && is_json_content)
            {
                var persist_dc = load_dict(is_persistent: true);
                var streaming_dc = load_dict(is_persistent: false);
                var merged_dc = MergeDictionaries(persist_dc, streaming_dc, overwrite);
                this.content_dc = merged_dc;
                save();
            }
            else
            {
                copy_streaming_to_persistent(overwrite: overwrite);
            }

            content_text = load_text();
            if (is_json_content)
                content_dc = BdUtils.conv_json_to_dict(content_text);
        }
        
        public string my_get_file_path(string file_name, string dir_name = "", bool is_persistent = true)
        {
            string res;

            relative_file_path = BdUtils.join(dir_name, file_name);
            // BdUtils.log("=== relative_file_path:", relative_file_path);
            if (is_persistent)
            {
                res = BdUtils.join(BdUtils.persistant_data_dir_path, relative_file_path);
            }
            else
            {
                res = BdUtils.join(BdUtils.streaming_data_dir_path, relative_file_path);
            }

            // if (BdUtils.is_null(dir_name))
            // {
            //     res = BdUtils.join(BdUtils.persistant_data_dir_path, file_name);
            // }
            // else
            // {
            //     res = BdUtils.join(BdUtils.persistant_data_dir_path, dir_name, file_name);
            // }
            return res;
        }

        public string get_abs_path(bool is_persistent = true)
        {
            string res = is_persistent ? persistent_file_path : streaming_file_path;
            return res;
        }

        // 读取文件内容为text
        public string load_text(bool is_persistent = true)
        {
            string abs_path = get_abs_path(is_persistent);
            BdUtils.assert(File.Exists(abs_path), $"文件路径不存在? abs_path: [{abs_path}]");
            string res = File.ReadAllText(abs_path);
            return res;
        }

        // 读取文件内容为json
        public Dictionary<string, object> load_dict(bool is_persistent = true)
        {
            string text = load_text(is_persistent);
            var dc = BdUtils.conv_json_to_dict(text);
            return dc;
        }

        // 保存内容
        public void save()
        {
            string f_path = persistent_file_path;
            string f_content = is_json_content ? BdUtils.conv_obj_to_json(content_dc) : content_text;
            // System.IO.File.Exists()
            if (!File.Exists(f_path))
            {
                string folderPath = Path.GetDirectoryName(f_path);
                Directory.CreateDirectory(BdUtils.conv_to_string(folderPath));
                File.Create(f_path).Close();
            }
            File.WriteAllText(f_path, f_content);
        }

        // 删除已存在的persistent, 并重置`content_dc`内容字典
        public bool remove_existed_persistent_file(bool is_reload_content = true)
        {
            bool ret = false;
            if (File.Exists(persistent_file_path))
            {
                File.Delete(persistent_file_path);
                ret = true;
            }

            if (is_reload_content)
            {
                // BdUtils.TimeUtils.sleep(0.01);
                // BdUtils.assert(!BdUtils.exists_file(persistent_file_path), "persistent_file_path没删掉??");
                reload_content_from_streaming();
            }

            return ret;
        }
        
        void reload_content_from_streaming()
        {
            content_dc = load_dict(is_persistent: false);
        }

        public void copy_streaming_to_persistent(bool overwrite = false)
        {
            BdUtils.log(" --- my_get_file_path.overwrite:", overwrite);
            if (!File.Exists(persistent_file_path) || overwrite)
            {
                BdUtils.assert(File.Exists(streaming_file_path), $"*** streaming_file_path[{streaming_file_path}]不存在?");
                BdUtils.copy_file_from_streaming_to_persistant(relative_file_path, overwrite: overwrite);
            }
        }
    }
}